---
title: "Foreach"
sidebarTitle: "Foreach Syntax"
description: "Foreach syntax add the flexibility of running action per result instead of only once on all results."
---

## Usage
There are two main operations mode for `foreach`:
1. In the [steps](#steps-section) section.
2. In the [action](#actions-section) section.

When you enter a `foreach` context, you can use `{{ foreach.value }}` to use the specific value.
Let's review how to use `foreach`.

### Steps section
Using `foreach` in `steps`, let you run a step for each result of a previous step.
In other words:
1. Run some step.
2. For each result of the previous step, run another step.

For example, in this alert, we:
1. Get all node id's (`get-node-ids` step).
2. For each node, get the data for result id (`get-filesystems-by-node-id` step).

```yaml
  steps:
    # Get all nodes ids
    - name: get-node-ids
      provider:
        type: postgres
        config: "{{ providers.postgres-server }}"
        with:
          query: "select distinct(node_id) from filesystem;"
    # For each node id, get the filesystem status and find filesystems in node that are not balanced
    - name: get-filesystems-by-node-id
      foreach: "{{ steps.get-node-ids.results }}"
      provider:
        type: postgres
        config: "{{ providers.postgres-server }}"
        with:
          query: "select * from filesystem where node_id = '{{ foreach.value[0] }}';"
```


In this case, `foreach.value` contains a row from the database, and `foreach.value[0]` is the first column of this row.

### Actions section
Now, let's see how `foreach` can be used in the `actions` section.

In the following example, we are using `foreach` twice:
1. `foreach: "{{ steps.get-filesystems-by-node-id.results }}"` - iterate over the results of `get-filesystems-by-node-id` results
2. `{{#foreach.stddev}}` - using mustache syntax, we iterate over `foreach.stddev` results.

#### Wait, but what's `foreach.stddev`?
> **tldr**: conditions can extend `foreach` with other attributes, to support more context.

Due to the fact that conditions work on `foreach.value`, we can extend `foreach` with other attributes.
For example, the `threshold` condition extends `foreach` with `level`, so you can use `foreach.level`, and `stddev` condition extends `foreach` with `stddev` attribute.


```yaml
actions:
    - name: push-alert-to-postgres
      # Run on get-filesystems-by-node-id results.
      # Notice each result is a list of filesystems in node
      foreach: "{{ steps.get-filesystems-by-node-id.results }}"
      # Alert on nodes that have filesystems that away from the standard deviation
      condition:
        - name: stddev-condition
          type: stddev
          # foreach.value contain a list of rows from the database
          value:  "{{ foreach.value }}"
          pivot_column: 8 # 8th column is the filesystem usage percentage
          compare_to: 1

      provider:
        type: postgres
        config: "{{ providers.postgres-server }}"
        with:
          query: >
            INSERT INTO alert (alert_level, alert_message)
            VALUES ('major', 'The node {{ foreach.value[0][4] }} has filesystems that are not balanced:
                    {{#foreach.stddev}}
                    - Filesystem {{ value[0] }} is {{stddev}} away from the standard deviation
                    {{/foreach.stddev}}')
```
